/*
 * vpir.c: A plugin for the Video Disk Recorder
 *
 * See the README file for copyright information and how to reach the author.
 *
 * $Id$
 */

#include <vdr/plugin.h>
#include <vdr/remote.h>
#include <vdr/thread.h>

#include <stdio.h>

#include "vp_remote.h"
#include "i18n.h"

/*-----------------------------------------------------------------------------
				REMOTE CLASS
-----------------------------------------------------------------------------*/


//#define dsyslog(	dsyslog("VISION PLUS REMOTE: "

class cVPIRSetupMenu;

class cVPIR : public cRemote, private cThread {
private:
  virtual void Action(void);
  char *device;
  int started;
public:
  int dev;
  cVPIR(const char *Name, char *dev);
  ~cVPIR(); 
  bool open_dev();
  virtual bool Initialize(void);
  virtual void Stop(void);
  virtual bool Put(uint64 Code, bool Repeat = false, bool Release = false);
  };

  
cVPIR::cVPIR(const char *Name, char *dev)
:cRemote(Name)
{
  device = dev;
  started = 0;
  Start();
}

cVPIR::~cVPIR()
{
}

bool cVPIR::open_dev()
{
	#define REMAP(idx, val)	if ( !vp_remap(dev, (idx), (val) ) ) \
					dsyslog("Error vp_remap\n");
	if (dev)
		close(dev);
	dev = open(device, OPEN_FLAGS);
	if ( dev == -1 ){
		  dsyslog("Error opening %s.", device);
		  dev = 0;
	} else {
		started = 1;
		vp_sendcmd(dev, CMD_REMAP_ON);
		vp_sendcmd(dev, CMD_CLEAR_TABLE);
		vp_sendcmd(dev, CMD_LOCK_DEVICE);
		REMAP( KEY_POWER0, 0 )
		REMAP( KEY_POWER1, 0 )
		REMAP( KEY_LEFT0, 0 )
		REMAP( KEY_RIGHT0, 0 )
	}
  return dev != 0;
}


bool cVPIR::Initialize()
{
	open_dev();
	return true; //olways load plugin
}

void cVPIR::Stop(void)
{
	if (dev)
		close(dev);
}

void cVPIR::Action(void)
{
	if ( !started )
		open_dev();
	if (dev){
		while ( 1 ) {
			unsigned char cmd = 0;
			int retval = read(dev, &cmd, 1);
			if ( retval && cmd ) {
				Put(cmd);
#ifdef DEBUG
				dsyslog("VISIONPLUSPILOT: pressed key: %d\n", cmd);
#endif
			} else {
				usleep( 100 );
			}
		}	
	}
}

bool cVPIR::Put(uint64 Code, bool Repeat, bool Release)
{
    return cRemote::Put(Code, Repeat, Release);
}





static const char *VERSION        = "0.1.1";
static const char *DESCRIPTION    = "Vision Plus 1022A IR port control for vdr";
static const char *MAINMENUENTRY  = "Vision Plus Pilot";
static cVPIR * dev_controller;


/*-----------------------------------------------------------------------------
				SETUP CLASS
-----------------------------------------------------------------------------*/


class cVPIRSetupMenu : public cMenuSetupPage {
protected:

public:
	cVPIRSetupMenu(void);
	eOSState ProcessKey(eKeys Key);
	virtual void Store(void);
};

cVPIRSetupMenu::cVPIRSetupMenu()
{
	Add(new cOsdItem(tr("(re)open IR port device"), osUser1));	
}

void cVPIRSetupMenu::Store(void)
{

}

eOSState cVPIRSetupMenu::ProcessKey(eKeys Key) {
	eOSState state = cMenuSetupPage::ProcessKey(Key);
	if (state == osUser1) {
		Skins.Message(mtInfo, tr("(re)opening device ..."));
		dev_controller = new cVPIR(MAINMENUENTRY, REMOTE_DEV);
		if (dev_controller){
			sleep(0);
			if ( dev_controller->dev )
				Skins.Message(mtInfo, tr("Success ;-)"));
			else
				Skins.Message(mtError, tr("Error opening IR port device!"));
		} else {
			Skins.Message(mtError, tr("Unknown ERROR!"));
		}
		sleep(1);
		Skins.Message(mtInfo, NULL);
		return osContinue;
	}
	return state;
}


/*-----------------------------------------------------------------------------
				PLUGIN CLASS
-----------------------------------------------------------------------------*/


class cPluginVpir : public cPlugin {
private:
  // Add any member variables or functions you may need here.
public:
  cPluginVpir(void);
  virtual ~cPluginVpir();
  virtual const char *Version(void) { return VERSION; }
  virtual const char *Description(void) { return tr(DESCRIPTION); }
  virtual const char *CommandLineHelp(void);
  virtual bool ProcessArgs(int argc, char *argv[]);
  virtual bool Initialize(void);
  virtual bool Start(void);
  virtual void Stop(void);
  virtual void Housekeeping(void);
//  virtual const char *MainMenuEntry(void) { return MAINMENUENTRY; }
  virtual cOsdObject *MainMenuAction(void);
  virtual cMenuSetupPage *SetupMenu(void);
  virtual bool SetupParse(const char *Name, const char *Value);
};

cPluginVpir::cPluginVpir(void)
{
  // Initialize any member variables here.
  // DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
  // VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
}

cPluginVpir::~cPluginVpir()
{
  // Clean up after yourself!
}

const char *cPluginVpir::CommandLineHelp(void)
{
  // Return a string that describes all known command line options.
  return NULL;
}

bool cPluginVpir::ProcessArgs(int argc, char *argv[])
{
  // Implement command line argument processing here if applicable.
  return true;
}

bool cPluginVpir::Initialize(void)
{
  // Initialize any background activities the plugin shall perform.
  RegisterI18n(Phrases);
  return true;
}

bool cPluginVpir::Start(void)
{
  // Start any background activities the plugin shall perform.
  dev_controller = new cVPIR(MAINMENUENTRY, REMOTE_DEV);
  return true;
}

void cPluginVpir::Stop(void)
{
  // Stop any background activities the plugin shall perform.
}

void cPluginVpir::Housekeeping(void)
{
  // Perform any cleanup or other regular tasks.
}

cOsdObject *cPluginVpir::MainMenuAction(void)
{
  // Perform the action when selected from the main VDR menu.
  return NULL;
}

cMenuSetupPage *cPluginVpir::SetupMenu(void)
{
  // Return a setup menu in case the plugin supports one.
  return new cVPIRSetupMenu;
}

bool cPluginVpir::SetupParse(const char *Name, const char *Value)
{
  // Parse your own setup parameters and store their values.
  return false;
}


VDRPLUGINCREATOR(cPluginVpir); // Don't touch this!
